package com.cy.pj.modules.service.impl;

import com.alibaba.fastjson.JSON;
import com.cy.pj.common.bo.PageObject;
import com.cy.pj.common.exception.ServiceException;
import com.cy.pj.common.utils.ShiroUtils;
import com.cy.pj.common.utils.SnowFlakeUtil;
import com.cy.pj.modules.constant.OrderConstant;
import com.cy.pj.modules.entity.Client;
import com.cy.pj.modules.entity.Order;
import com.cy.pj.modules.entity.OrderItem;
import com.cy.pj.modules.entity.Sku;
import com.cy.pj.modules.mapper.ClientMapper;
import com.cy.pj.modules.mapper.OrderItemMapper;
import com.cy.pj.modules.mapper.OrderMapper;
import com.cy.pj.modules.mapper.SkuMapper;
import com.cy.pj.modules.service.IOrderService;
import com.cy.pj.modules.service.ISkuService;
import com.cy.pj.modules.vo.OrderSkusVo;
import com.cy.pj.modules.vo.OrderVo;
import com.cy.pj.modules.vo.SkuVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author kiven
 * @date 2023-03-07
 */
@Service
public class OrderServiceImpl implements IOrderService
{
    @Autowired
    private OrderMapper orderMapper;

    @Value("${fz.pageHelper.pageSize}")
    private Integer pageSize;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ISkuService skuService;
    @Autowired
    private SkuMapper skuMapper;

    // 会员折扣
    @Value("${fz.memberDiscount}")
    private String memberDiscount;

    @Value("${fz.zx}")
    private Long zxId;
    @Value("${fz.jq}")
    private Long jqId;

    @Value("${fz.manager}")
    private String manager;
    @Autowired
    private ClientMapper clientMapper;
    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】ID
     * @return 【请填写功能名称】
     */
    @Override
    public Order selectOrderById(String id)
    {
        return orderMapper.selectOrderById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param order 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public PageObject<OrderVo> selectOrderList(Order order, Integer pageCurrent)
    {
        //1.参数校验
        if (pageCurrent == null || pageCurrent < 1) {
            throw new IllegalArgumentException("页码值无效");
        }
        //2.设置分页参数
        String orderBy = "id desc";
        Page<Order> page = PageHelper.startPage(pageCurrent, pageSize, orderBy);
        //3.查询当前页记录
        List<Order> list = orderMapper.selectOrderList(order);
        List<OrderVo> orderVos = new ArrayList<>();
        //4. 存储OrderVo的订单商品值
        for (Order order1 : list) {
            OrderVo orderVo = new OrderVo();
            List<OrderItem> orderItems = new ArrayList<>();
            orderItems = orderItemMapper.selectOrderItemByOrderId(order1.getId());
            orderVo = JSON.parseObject(JSON.toJSONString(order1),OrderVo.class);
            List<Map<String,String>> list1 = new ArrayList<>();
            for (OrderItem orderItem : orderItems) {
                Map<String,String> map = new HashMap<>();
                Sku sku = skuMapper.selectSkuById(Long.parseLong(orderItem.getSkuId()));
                map.put("名称",orderItem.getName());
                map.put("规格",sku.getSpecifications());
                map.put("价格",sku.getPrice().toString());
                map.put("数量",orderItem.getNum()+"");
                list1.add(map);
            }
            orderVo.setOrderItemsStrs(JSON.toJSONString(list1));
            orderVos.add(orderVo);
        }

        return new PageObject<>(orderVos, (int) page.getTotal(), page.getPages(), pageSize, pageCurrent);
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param order 【请填写功能名称】
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertOrder(OrderSkusVo order)
    {

        if(manager.equals(ShiroUtils.getUsername())){
            throw new ServiceException("请使用店铺人员账号新增订单");
        }

        if(StringUtils.isEmpty(order.getUsername())){
            throw new ServiceException("请提供开单员工账号");
        }
        if(order.getOrderItems().size()==0){
            throw new ServiceException("请添加商品后下单");
        }

        // 重新计算订单总价
        // 验证是否有库存
        // 新增订单和商品那里对象不一样 所以要复制属性过去
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(order,orderVo);
        SnowFlakeUtil snowFlakeUtil = new SnowFlakeUtil(zxId,jqId);
        long orderId = snowFlakeUtil.nextId();
        List<SkuVo> orderSkus = JSON.parseArray(JSON.toJSONString(order.getOrderItems()),SkuVo.class);
        // 按照skuId 排个序,避免修改多条sku,加了排他锁的, 最后造成死锁
        orderSkus = orderSkus.stream().sorted(Comparator.comparing(SkuVo::getId)).collect(Collectors.toList());
        List<OrderItem> orderItems1 = new ArrayList<>();
        for (int i1 = 0; i1 < orderSkus.size(); i1++) {
            SkuVo skuVo = JSON.parseObject(JSON.toJSONString(orderSkus.get(i1)),SkuVo.class);
            OrderItem orderItem1 = new OrderItem();
            orderItem1.setSkuId(skuVo.getId()+"");
            orderItem1.setPrice(skuVo.getPrice().toString());
            orderItem1.setNum(Integer.parseInt(skuVo.getNum()+""));
            orderItems1.add(orderItem1);
        }
        orderVo.setOrderItems(orderItems1);
        Map<String, String> stringStringMap = sumPrice(orderVo);

        order.setPayMoney(stringStringMap.get("payPrice"));
        order.setTotalMoney(stringStringMap.get("sumPrice"));
        order.setPreMoney(stringStringMap.get("preMoney"));
        // 准备数据插入订单
        order.setCreateTime(new Date());
        order.setPayStatus(OrderConstant.NO_PAY);
        order.setOrderStatus(OrderConstant.UNFINISHED);
        order.setId(orderId+"");
        int i = orderMapper.insertOrder(order);
        if(i==0){
            throw new ServiceException("业务繁忙,新增订单失败");
        }
        // 准备扣减库存 加了排他锁, 并且为了防止死锁, 我把orderSkus 集合内容根据id做了排序,按顺序处理多条修改,就不会死锁了
        for (int i1 = 0; i1 < orderSkus.size(); i1++) {
            SkuVo skus = JSON.parseObject(JSON.toJSONString(orderSkus.get(i1)),SkuVo.class);
            Sku sku1 = skuMapper.selectSkuByIdForUpdate(skus.getId());
            Sku sku = new Sku();
            sku.setId(skus.getId());
            sku.setNumber(sku1.getNumber()-Long.parseLong(skus.getNum()));
            i = skuService.updateSku(sku);
        }
        if(i==0){
            throw new ServiceException("下单失败,扣减库存失败");
        }
        // 构建订单商品数据, 插入订单商品表.
        for (SkuVo skus : orderSkus) {
            long l = snowFlakeUtil.nextId();
            OrderItem orderItem = new OrderItem();
            orderItem.setNum(Integer.parseInt(skus.getNum()));
            orderItem.setPrice(skus.getPrice().toString());
            orderItem.setOrderId(order.getId());
            orderItem.setSkuId(skus.getId()+"");
            orderItem.setAddTime(order.getCreateTime());
            orderItem.setSpuId(skus.getSpuId()+"");
            orderItem.setImage(skus.getUrl());
            orderItem.setName(skus.getName());
            orderItem.setId(l+"");
            orderItemMapper.insertOrderItem(orderItem);
        }
        // 为客户增加积分 价格/10 四舍五入
        if(StringUtils.isNotEmpty(order.getMemberId())){
            DecimalFormat format = new DecimalFormat("0");
            BigDecimal divide = new BigDecimal(order.getTotalMoney()).divide(new BigDecimal(10));
            String score = format.format(divide);
            Client client1 = clientMapper.selectClientByIdOrByMobile(Long.parseLong(order.getMemberId()));
            Client client = new Client();
            client.setId(client1.getId());
            client.setScore(client1.getScore()+Long.parseLong(score));
            clientMapper.updateClient(client);
        }
        return i;
    }

    /**
     * 修改【请填写功能名称】
     *
     * @param order 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateOrder(Order order)
    {
        order.setUpdateTime(new Date());
        return orderMapper.updateOrder(order);
    }

    /**
     * 删除【请填写功能名称】对象
     *
     *
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteOrderByIds(String idsStr)
    {
        String[] ids = idsStr.split(",");
        // 回滚用户积分
        for (String id : ids) {
            Order order = orderMapper.selectOrderById(id);
            if (StringUtils.isNotEmpty(order.getMemberId())) {
                DecimalFormat format = new DecimalFormat("0");
                BigDecimal divide = new BigDecimal(order.getTotalMoney()).divide(new BigDecimal(10));
                String score = format.format(divide);
                Client client1 = clientMapper.selectClientByIdOrByMobile(Long.parseLong(order.getMemberId()));
                Client client = new Client();
                client.setId(client1.getId());
                client.setScore(client1.getScore() - Long.parseLong(score));
                clientMapper.updateClient(client);
            }
        }
        int i = orderMapper.deleteOrderByIds(ids);
        // 准备回滚sku库存
        if(i==0){
            return i;
        }
        // 删除orderItemMapper ,回滚sku库存
        for (String id : ids) {
            List<OrderItem> orderItems = orderItemMapper.selectOrderItemByOrderId(id);
            // 按照skuId 排个序,避免修改多条sku,加了排他锁的, 最后造成死锁
            orderItems = orderItems.stream().sorted(Comparator.comparing(OrderItem::getId)).collect(Collectors.toList());
            for (OrderItem orderItem : orderItems) {
                // 修改sku库存
                Sku sku1 = skuMapper.selectSkuByIdForUpdate(Long.parseLong(orderItem.getSkuId()));
                Sku sku = new Sku();
                sku.setId(sku1.getId());
                sku.setNumber(sku1.getNumber()+Long.parseLong(orderItem.getNum()+""));
                skuService.updateSku(sku);
            }

            //  批量删除
            List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
            orderItemMapper.deleteOrderItemByIds(orderItemIdList.stream().toArray(String[]::new));
        }

        return i;
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】ID
     * @return 结果
     */
    @Override
    public int deleteOrderById(String id)
    {
        return orderMapper.deleteOrderById(id);
    }


    @Override
    public Map<String,String> sumPrice(OrderVo orderVo) {
        Map<String,String> resultMap = new HashMap<>();
        // 计算总价, 是否会员
        // 根据传输的商品集合 来计算总价
        List<OrderItem> orderItems = orderVo.getOrderItems();
        BigDecimal bigDecimal = new BigDecimal("0.0");
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        for (OrderItem orderItem : orderItems) {
            // 从数据库拿出来计算
            Sku sku = skuMapper.selectSkuById(Long.parseLong(orderItem.getSkuId()));
            try {
                BigDecimal cyj = new BigDecimal(sku.getPrice().toString());
                BigDecimal qdyj = new BigDecimal(orderItem.getPrice());
                BigDecimal subtract = cyj.subtract(qdyj);
                String s = subtract.toPlainString();
                if (Boolean.parseBoolean(s)) {
                    throw new ServiceException("价格异常,操作失败! sku id: " + sku.getId() + ", sku price: " + sku.getPrice() + ", order item id: " + orderItem.getId() + ", order item price: " + orderItem.getPrice());
                }
            } catch (NumberFormatException e) {
                throw new ServiceException("价格格式错误,操作失败!", e);
            }
            // 且判断库存是否充足
            if(sku.getNumber()<=0||orderItem.getNum()>sku.getNumber()){
                throw new ServiceException("该商品添加失败,库存不足,请准备进货或者跨店调配");
            }
            String price = orderItem.getPrice();
            Integer num = orderItem.getNum();
            BigDecimal bigDecimal1 = new BigDecimal(price);
            // 单款总价
            BigDecimal multiply = bigDecimal1.multiply(new BigDecimal(num));
            bigDecimal = bigDecimal.add(multiply);
        }
        // 存总价格
        resultMap.put("sumPrice",decimalFormat.format(bigDecimal));
        // 如果是会员 数据库查询
        if(StringUtils.isNotEmpty(orderVo.getMemberId())){
            Client client = clientMapper.selectClientByIdOrByMobile(Long.parseLong(orderVo.getMemberId()));
            if(client!=null){
                bigDecimal = bigDecimal.multiply(new BigDecimal(memberDiscount));
            }else{
                throw new RuntimeException("该会员不存在");
            }
        }
        // 存实付价格
        resultMap.put("payPrice",decimalFormat.format(bigDecimal));

        // 计算优惠价格
        BigDecimal bigDecimal1 = new BigDecimal(resultMap.get("sumPrice"));
        bigDecimal1 = bigDecimal1.subtract(new BigDecimal(resultMap.get("payPrice")));
        resultMap.put("preMoney",decimalFormat.format(bigDecimal1));
        return resultMap;
    }
}
